package com.sti.platform.util.logannotation;


import java.lang.reflect.Method;
import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.util.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import com.sti.platform.model.SysLog;
import com.sti.platform.service.SysLogService;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.alibaba.fastjson.JSONObject;

/**
 *
 * @Description 日志记录
 * @author fengjk
 * @date 2017-5-2 下午3:24:37
 */
@Aspect
@Component
public class SystemLogAspect{
    // 注入Service用于把日志保存数据库
    @Autowired
    private SysLogService sysLogService;
    //private static final Logger logger = LoggerFactory.getLogger(SystemLogAspect.class);

    @Pointcut("@annotation(com.sti.platform.util.logannotation.LogAnnotation)")
    public void beforeLog() {//只 拦截 带注解的 @LogAnnotation 的方法

    }
    @Pointcut("@annotation(com.sti.platform.util.logannotation.LogAnnotation)")
    public void controllerAspect(){//只 拦截 带注解的 @LogAnnotation 的方法

    }

    /**
     *
     * @Description 前置通知
     * @author fengjk
     * @date 2017-5-23 下午6:22:07
     */

    @Before(value = "beforeLog()")//@Pointcut(value="切入点表达式", argNames = "参数名列表")
    public void beforePointCut(){//切入前。要执行的方法

    }

    /**
     *
     * @Description 后置通知，记录用户在Controller操作记录
     * @author fengjk
     * @date 2017-4-26 上午11:26:59
     */
    @AfterReturning(pointcut = "controllerAspect()", returning = "res")
    public void afterPointCut(JoinPoint joinPoint, Object res) {//切入后

        try {

            Class[] parameterTypes = ((MethodSignature)joinPoint.getSignature()).getMethod().getParameterTypes();
            Method method = null;
            String methodName = joinPoint.getSignature().getName();//方法名字
            Class targetClass = joinPoint.getTarget().getClass();
            String controllerName = targetClass.getName();//访问的类的名字
            method = targetClass.getMethod(methodName,parameterTypes);
            boolean hasAnnotation = method.isAnnotationPresent(LogAnnotation.class);
            if(hasAnnotation){
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                String methodType= request.getMethod();
                InetAddress inetAddress = InetAddress.getLocalHost();
                String ip = inetAddress.getHostAddress();
                String url = request.getRequestURI();
                // 读取session中的用户
                HttpSession session = request.getSession();
                //String loginName = (String) session.getAttribute("loginName");
                //Long userId = (Long) session.getAttribute("userId");
                String logConent = method.getAnnotation(LogAnnotation.class).logConent();//日志的内容
                // -------------------执行系统 的插入 日志----------------------------
                Date date = new Date();
                SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String dateStr=sdf.format(date);

                if(!StringUtils.isNotBlank(logConent)){//日志为空
                    logConent = "admin" + "请求了: "+ url +" 。IP: "+ip;
                }
                SysLog sysLog = new SysLog();
                sysLog.setContent(logConent);
                String type = chageType(methodName);//系统日志类型
                sysLog.setType(type);
                sysLog.setOptuserid("adminID123123");
                sysLog.setOptusername("admin");
                //操作模块这里暂时存 进入的类 后期改成
                // getOptUnit( controllerName)
                sysLog.setOptunit(controllerName);

                sysLogService.saveSysLog(sysLog);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据 类的名字 获取操作模块
     * 暂时保存类的名字
     * */
    public String getOptUnit(String controllerName){
        Map map = new HashMap();
        map.put("com.sti.platform.controller.SysLogController","系统日志模块");
        map.put("com.sti.platform.controller.RoleCotroller","角色模块");
        map.put("com.sti.platform.controller.ResourceController","资源模块");
        map.put("com.sti.platform.controller.IndexController","资源模块");
        String returnName = controllerName.trim();
        for(Object key : map.keySet()){
                if(controllerName.equals(key.toString())){
                    returnName = map.get(key).toString();
                }
        }

        return returnName;
   }

    /**根据方法名字，判读日志类型，方法的名字按照约定应该是 */
    public String chageType(String param){
        ///**类型 0：增加数据、1：修改数据、2：删除数据、3：登录系统、4：其他、5：查询数据、9：系统异常*/
        String []patternAdd = {"add","save"};//增
        String []patternUpdate = {"upd","update","upt"};//改
        String []patternDel= {"del","delete"};//删
        String []patternSelect = {"list","sele","go","index","jump"};//查
        String []patternLogin = {"login"};//查
        // Arrays.asList(patternAdd).contains(param) 这个是包含，不是全局匹配
        for(String obj : patternAdd){
            if(obj.indexOf(param)!=-1){//0：增加数据
                return "0";
            }
        }
        for(String obj : patternUpdate){
            if(obj.indexOf(param)!=-1){//1：修改数据
                return "1";
            }
        }
        for(String obj : patternDel){
            if(obj.indexOf(param)!=-1){//2：删除数据
                return "2";
            }
        }
        for(String obj : patternLogin){
            if(obj.indexOf(param)!=-1){//3：登录系统
                return "3";
            }
        }
        for(String obj : patternSelect){
            if(obj.indexOf(param)!=-1){//5：查询数据
                return "5";
            }
        }
        return "4";
    }
}